package com.geeksaga.filter;

import java.io.IOException;
import java.util.Calendar;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.geeksaga.common.util.KeyGenerator;
import com.geeksaga.common.util.SessionManager;
import com.geeksaga.dao.CounterDao;
import com.geeksaga.domain.Counter;

/**
 * @author newbie
 * @since 0.1
 */
public class CounterFilter implements Filter {

    protected static final Log logger = LogFactory.getLog(CounterFilter.class);
    protected FilterConfig filterConfig = null;

    public void destroy() {
        this.filterConfig = null;
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
            ServletException {

        HttpServletRequest httpServletRequest = (HttpServletRequest) request;

        HttpSession httpSession = httpServletRequest.getSession();

        if (httpSession.getAttribute("counter") == null) {
            WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(httpSession
                    .getServletContext());
            CounterDao counterDao = ctx.getBean(CounterDao.class);
            counterDao.add(makeCounter(httpServletRequest));

            httpSession.setAttribute("counter", new HttpSessionBindingListenerImpl());
        }

        chain.doFilter(request, response);
    }

    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
    }

    private Counter makeCounter(HttpServletRequest request) {
        Counter counter = new Counter();
        counter.setSid(KeyGenerator.generatorKey());
        counter.setIp(request.getRemoteAddr());
        counter.setReferer(request.getHeader("Referer"));
        // counter.setBrowser(browser);
        // counter.setOs(os);
        counter.setDayOfWeek(String.valueOf(Calendar.getInstance().get(Calendar.DAY_OF_WEEK)));
        counter.setUserAgent(request.getHeader("User-Agent"));

        return counter;
    }
}

class HttpSessionBindingListenerImpl implements HttpSessionBindingListener {
    String id;
    String value;
    SessionManager sessionManager;

    public HttpSessionBindingListenerImpl() {
        value = "counter";
    }

    public void valueBound(HttpSessionBindingEvent event) {
        HttpSession httpSession = event.getSession();
        id = httpSession.getId();
        sessionManager = SessionManager.getInstance();
        sessionManager.addClient(id, value);
    }

    public void valueUnbound(HttpSessionBindingEvent event) {
        HttpSession httpSession = event.getSession();
        id = httpSession.getId();
        sessionManager = SessionManager.getInstance();
        sessionManager.removeClient(id);
    }
}